package oocis.util;

import java.util.*;

public class Time {
	final int dayInMonth[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

	/*
	 * year,month,day,hour,minut,second
	 */
	int yy, mm, dd, hh, mmm, ss;

	public Time() {
		Calendar cal = java.util.Calendar.getInstance();

		setTime(cal.get(cal.YEAR), cal.get(cal.MONTH) + 1, cal
				.get(cal.DAY_OF_MONTH), cal.get(cal.HOUR_OF_DAY), cal
				.get(cal.MINUTE), cal.get(cal.SECOND));
	}

	public Time(int y, int m, int d, int h, int mi, int s) {
		setTime(y, m, d, h, mi, s);
	}

	public Time(String y, String m, String d, String h, String mi, String s) {
		setTime(y, m, d, h, mi, s);
	}

	int cat(Long a) {
		return a.intValue();
	}

	public Time(Long code) {
		long p = code;
		ss = cat(p % 100);
		p /= 100;
		mmm = cat(p % 100);
		p /= 100;
		hh = cat(p % 100);
		p /= 100;
		dd = cat(p % 100);
		p /= 100;
		mm = cat(p % 100);
		p /= 100;
		yy = cat(p);
	}

	public Time(String code) {
		this(Long.valueOf(code));
	}

	public Time(Time cptm) {
		setTime(cptm.yy, cptm.mm, cptm.dd, cptm.hh, cptm.mmm, cptm.ss);
	}

	public Long incode() {
		return Long.valueOf((long) ss + (long) mmm * 100 + (long) hh * 100
				* 100 + (long) dd * 100 * 100 * 100 + (long) mm * 100 * 100
				* 100 * 100 + (long) yy * 100 * 100 * 100 * 100 * 100);
	}

	/*
	 * Set the time that come from the plat.class.
	 */
	public void setTime(int y, int m, int d, int h, int mi, int s) {
		yy = y;
		mm = m;
		dd = d;
		hh = h;
		mmm = mi;
		ss = s;
	}

	public void setTime(String y, String m, String d, String h, String mi,
			String s) {
		yy = Integer.valueOf(y);
		mm = Integer.valueOf(m);
		dd = Integer.valueOf(d);
		hh = Integer.valueOf(h);
		mmm = Integer.valueOf(mi);
		ss = Integer.valueOf(ss);
	}

	/*
	 * Get the value of the ....
	 */

	public int getYear() {
		return yy;
	}

	public int getMonth() {
		return mm;
	}

	public int getDay() {
		return dd;
	}

	public int getHour() {
		return hh;
	}

	public int getMinute() {
		return mmm;
	}

	public int getSecond() {
		return ss;
	}

	/*
	 * Check whether this year is leap year.
	 */

	public boolean leapYear() {
		if (yy % 4 == 0 && yy % 100 != 0)
			return true;
		if (yy % 400 == 0)
			return true;
		return false;
	}

	/*
	 * Check whether the value of arrtribution in the interzone time. By the
	 * way, for the real time in our life.
	 */

	boolean validYear() {
		return yy > 0;
	}

	boolean validMonth() {
		return mm > 0 && mm <= 12;
	}

	boolean validDay() {
		return dd > 0
				&& (dd <= dayInMonth[mm] || (leapYear() && mm == 2 && dd == 29));
	}

	boolean validHour() {
		return hh >= 0 && hh < 24;
	}

	boolean validMinut() {
		return mmm >= 0 && mmm < 60;
	}

	boolean validSecond() {
		return ss >= 0 && ss < 60;
	}

	/*
	 * Check this time is real time.
	 */

	public boolean valid() {
		return validYear() && validMonth() && validDay() && validHour()
				&& validMinut() && validSecond();
	}

	/*
	 * Go to the next time point that is past tm from now on.
	 */

	public Time goNextTime(Time tm) {
		if (!tm.valid())
			return this;
		int hipUp = 0;
		ss += tm.ss;
		while (!validSecond()) {
			hipUp++;
			ss -= 60;
		}
		mmm += hipUp + tm.mmm;
		hipUp = 0;
		while (!validMinut()) {
			hipUp++;
			mmm -= 60;
		}
		hh += hipUp + tm.hh;
		hipUp = 0;
		while (!validHour()) {
			hipUp = 1;
			hh -= 24;
		}
		dd += hipUp + tm.dd;
		hipUp = 0;
		while (!validDay()) {
			hipUp++;
			if (!leapYear() || mm != 2)
				dd -= dayInMonth[mm];
			else
				dd -= 29;

		}
		mm += hipUp + tm.mm;
		hipUp = 0;
		while (!validMonth()) {
			hipUp++;
			mm -= 12;
		}
		yy += hipUp + tm.yy;
		return this;
	}

	/*
	 * Next time point from now on.
	 */

	public Time nextTime(Time tm) {
		Time newTime = new Time(this);
		return newTime.goNextTime(tm);
	}

	public Time nextSecond() {
		Time tm = new Time();
		tm.setTime(0, 0, 0, 0, 0, 1);
		return nextTime(tm);
	}

	public Time nextMinut() {
		Time tm = new Time();
		tm.setTime(0, 0, 0, 0, 1, 0);
		return nextTime(tm);
	}

	public Time nextHour() {
		Time tm = new Time();
		tm.setTime(0, 0, 0, 1, 0, 0);
		return nextTime(tm);
	}

	public Time nextDay() {
		Time tm = new Time();
		tm.setTime(0, 0, 1, 0, 0, 0);
		return nextTime(tm);
	}

	public Time nextMonth() {
		Time tm = new Time();
		tm.setTime(0, 1, 0, 0, 0, 0);
		return nextTime(tm);
	}

	public Time nextYear() {
		Time tm = new Time();
		Time abc;
		tm.setTime(1, 0, 0, 0, 0, 0);
		return nextTime(tm);
	}

	/*
	 * Relationship.
	 */

	public boolean lessThan(Time tm) {
		return yy < tm.yy
				|| (yy == tm.yy && mm < tm.mm)
				|| (yy == tm.yy && mm == tm.mm && dd < tm.dd)
				|| (yy == tm.yy && mm == tm.mm && dd == tm.dd && hh < tm.hh)
				|| (yy == tm.yy && mm == tm.mm && dd == tm.dd && hh == tm.hh && mmm < tm.mmm)
				|| (yy == tm.yy && mm == tm.mm && dd == tm.dd && hh == tm.hh
						&& mmm == tm.mmm && ss < tm.ss);

	}

	public boolean greaterThan(Time tm) {
		return yy > tm.yy
				|| (yy == tm.yy && mm > tm.mm)
				|| (yy == tm.yy && mm == tm.mm && dd > tm.dd)
				|| (yy == tm.yy && mm == tm.mm && dd == tm.dd && hh > tm.hh)
				|| (yy == tm.yy && mm == tm.mm && dd == tm.dd && hh == tm.hh && mmm > tm.mmm)
				|| (yy == tm.yy && mm == tm.mm && dd == tm.dd && hh == tm.hh
						&& mmm == tm.mmm && ss > tm.ss);
	}

	public boolean equal(Time tm) {
		return yy == tm.yy && mm == tm.mm && dd == tm.dd && hh == tm.hh
				&& mmm == tm.mmm && ss == tm.ss;
	}

	public boolean lessEqual(Time tm) {
		return !greaterThan(tm);
	}

	public boolean greaterEqual(Time tm) {
		return !lessThan(tm);
	}

	/*
	 * Give the nearest time --> make the important time point.
	 */

	public Time nearestTime(Time tm) {
		if (tm.lessThan(this))
			return this;
		else
			return null;
	}

	public static void main(String args[]) {
		System.out.println("~!!");
	}

}
